package impl

import (
	"context"
	"time"
	"vblog/app/blog"
	"vblog/conf"
	"vblog/ioc"

	"dario.cat/mergo"
	"gorm.io/gorm"
)

type BlogServiceImpl struct {
	db *gorm.DB
}

// 注册到ioc
func init() {
	ioc.Controller().RegistryIoc(&BlogServiceImpl{})
}

// 初始化
func (b *BlogServiceImpl) Init() {
	b.db = conf.C().Mysql.GetConn()
}

func (b *BlogServiceImpl) Name() string {
	return "blog"
}

func (b *BlogServiceImpl) CreateBlog(ctx context.Context, req *blog.CreateBlogRequest) (*blog.Blog, error) {
	ins := blog.NewBlog(req)
	if err := b.db.WithContext(ctx).Create(ins).Error; err != nil {
		return nil, err
	}

	return ins, nil
}

// 列表查询，返回的是列表
func (b *BlogServiceImpl) QueryBlog(ctx context.Context, req *blog.QueryBlogRequest) (*blog.BlogSet, error) {
	// 构造查询条件
	query := b.db.WithContext(ctx).Model(&blog.Blog{})
	if req.Status != nil {
		query = query.Where("status = ?",req.Status)
	}
	
	// 查询总数 (SELECT count(*) FROM `blogs` WHERE status = '0')
	t := blog.NewBlogSet()
	if err := query.Count(&t.Total).Error;  err != nil {
		return nil,err
	}

	// 查询一页的数据(SELECT * FROM `blogs` WHERE status = '1' LIMIT 10)
	err := query.Offset(req.MyOffset()).Limit(req.PageSize).Find(&t.Items).Error
	if err != nil {
		return nil,err
	}

	return t, nil
}

// 文章查询，返回的是一个对象
func (b *BlogServiceImpl) DescribeBlog(ctx context.Context, req *blog.DescribeBlogRequest) (*blog.Blog, error) {
	// 1.构造查询条件
	query := b.db.WithContext(ctx).Model(&blog.Blog{})

	// 2.查询
	ins := blog.NewBlog(blog.NewCreateBlogRequest())
	err := query.Where("id = ?",req.BlogId).First(ins).Error
	if err != nil {
		return nil, err
	}

	// 3.返回对象
	return ins, nil
}

func (b *BlogServiceImpl) UpdateBlogStatus(ctx context.Context, req *blog.UpdateBlogStatusRequest) (*blog.Blog, error) {
	return nil, nil
}

func (b *BlogServiceImpl) UpdateBlog(ctx context.Context, req *blog.UpdateBlogRequest) (*blog.Blog, error) {
	// 1.查询
	r1 := blog.NewDescribeBlogRequest()
	r1.BlogId = req.BlogId
	ins,err := b.DescribeBlog(ctx,r1)
	if err != nil {
		return nil, err
	}

	// 2.判断更新模式(全量和增量)
	switch req.UpdateMode {
	case blog.UPDATE_MODE_PUT:
		ins.CreateBlogRequest = req.CreateBlogRequest
	case blog.UPDATE_MODE_PATCH:
		// 先创建数据库对象的副本
		updateReq := blog.NewCreateBlogRequest()
		// 将数据库数据复制到副本
		if err := mergo.Merge(updateReq,ins.CreateBlogRequest,mergo.WithOverride); err != nil {
			return nil,err
		}
		// 将请求数据合并到副本中
		if err := mergo.Merge(updateReq,req.CreateBlogRequest,mergo.WithOverride); err != nil {
			return nil,err
		}
		// 使用合并后的副本
		ins.CreateBlogRequest = updateReq
	}

	// 补充Scope逻辑来更新
	// UPDATE `blogs` SET ... WHERE id = 'xx' AND create_by = 'xx'
    db := b.db.WithContext(ctx).Model(&blog.Blog{}).Where("id = ?", req.BlogId)

	if req.Scope != nil && req.Scope.UserId != "" {
		db = db.Where("create_by = ?",req.Scope.UserId)
	}
	
	if err = db.Updates(ins).Error; err != nil {
		return nil,err
	}

	// 3.更新
	// if err = b.db.WithContext(ctx).Updates(ins).Error; err != nil{
	// 	return nil,err
	// }

	// 4.返回
	return ins, nil
}

func (b *BlogServiceImpl) DeleteBlog(ctx context.Context, req *blog.DeleteBlogRequest) error {
	// 1.查询
	r1 := blog.NewDescribeBlogRequest()
	r1.BlogId = req.BlogId
	ins,err := b.DescribeBlog(ctx,r1)
	if err != nil {
		return err 
	}

	// 2.删除
	err = b.db.WithContext(ctx).Where("id = ?",r1.BlogId).Delete(ins).Model(&blog.Blog{}).Error
	if err != nil {
		return err
	}
	
	return nil
}


func (b *BlogServiceImpl) AuditBlog(c context.Context,req *blog.AuditBlogRequest) (*blog.Blog,error) {
	// 1.查询
	r := blog.NewDescribeBlogRequest()
	r.BlogId = req.BlogId
	ins,err := b.DescribeBlog(c,r)
	if err != nil {
		return nil, err
	}

	// 2.更新审核状态
	ins.IsAuditPass = req.IsAuditPass
	ins.AuditAt  = time.Now().Unix()
	err = b.db.WithContext(c).Model(&blog.Blog{}).Updates(ins).Error
	if err != nil {
		return nil, err
	}

	// 3.返回
	return ins,nil 
}